name: Python Release
on:
  push:
    tags:
      - v*

env:
  AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
  AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
  AWS_DEFAULT_REGION: us-east-1
  PYPI_TOKEN: ${{ secrets.PYPI_TOKEN_DIST }}
  DIST_DIR: ${{ github.sha }}

jobs:
  lock_exists:
    runs-on: ubuntu-latest
    name: Cargo.lock
    steps:
      - uses: actions/checkout@v3
      - name: Cargo.lock lock exists 
        run: cat Cargo.lock
        working-directory: ./bindings/python

  build:
    name: build on ${{ matrix.platform || matrix.os }} (${{ matrix.target }} - ${{ matrix.manylinux || 'auto' }})
    # only run on push to main and on release
    needs: [lock_exists]
    if: startsWith(github.ref, 'refs/tags/') || github.ref == 'refs/heads/main' || contains(github.event.pull_request.labels.*.name, 'Full Build')
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu, macos, windows]
        target: [x86_64, aarch64]
        manylinux: [auto]
        include:
          - os: ubuntu
            platform: linux
          - os: windows
            ls: dir
            interpreter: 3.7 3.8 3.9 3.10 3.11 3.12 pypy3.8 pypy3.9 pypy3.10
          - os: windows
            ls: dir
            target: x86_64
            python-architecture: x64
            interpreter: 3.7 3.8 3.9 3.10 3.11 3.12
          - os: windows
            ls: dir
            target: i686
            python-architecture: x86
            interpreter: 3.7 3.8 3.9 3.10 3.11 3.12
              # - os: windows
              #   ls: dir
              #   target: aarch64
              #   interpreter: 3.11 3.12
          - os: macos
            target: aarch64
            interpreter: 3.7 3.8 3.9 3.10 3.11 3.12 3.13 pypy3.8 pypy3.9 pypy3.10
          - os: ubuntu
            platform: linux
            target: i686
          - os: ubuntu
            platform: linux
            target: aarch64

          - os: ubuntu
            platform: linux
            target: armv7
            interpreter: 3.7 3.8 3.9 3.10 3.11 3.12 3.13
          # musllinux
          - os: ubuntu
            platform: linux
            target: x86_64
            manylinux: musllinux_1_1
          - os: ubuntu
            platform: linux
            target: aarch64
            manylinux: musllinux_1_1
          - os: ubuntu
            platform: linux
            target: ppc64le
            interpreter: 3.7 3.8 3.9 3.10 3.11 3.12 3.13
          - os: ubuntu
            platform: linux
            target: s390x
            interpreter: 3.7 3.8 3.9 3.10 3.11 3.12 3.13
        exclude:
          - os: windows
            target: aarch64
              #   # Optimized PGO builds for x86_64 manylinux and windows follow a different matrix,
              #   # maybe in future maturin-action can support this automatically
              #   - os: ubuntu
              #     target: x86_64
              #     manylinux: auto
              #   - os: windows
              #     target: x86_64
              # Windows on arm64 only supports Python 3.11+

    runs-on: ${{ matrix.os }}-latest
    steps:
      - uses: actions/checkout@v3

      - name: set up python
        uses: actions/setup-python@v4
        with:
          python-version: "3.12"
          architecture: ${{ matrix.python-architecture || 'x64' }}

      - run: pip install -U twine

      - name: build wheels
        uses: PyO3/maturin-action@v1
        with:
          target: ${{ matrix.target }}
          working-directory: ./bindings/python
          manylinux: ${{ matrix.manylinux || 'auto' }}
          container: ${{ matrix.container }}
          args: --release --out dist --interpreter ${{ matrix.interpreter || '3.7 3.8 3.9 3.10 3.11 3.12 3.13 pypy3.7 pypy3.8 pypy3.9 pypy3.10' }} ${{ matrix.extra-build-args }}
          rust-toolchain: stable
          docker-options: -e CI

      - run: ${{ matrix.ls || 'ls -lh' }} dist/
        working-directory: ./bindings/python

      - run: twine check --strict dist/*
        working-directory: ./bindings/python

      - name: Upload wheels
        shell: bash
        run: |
          pip install awscli
          aws s3 sync --exact-timestamps ./bindings/python/dist "s3://tokenizers-releases/python/$DIST_DIR"

          # - uses: actions/upload-artifact@v3
          #   working-directory: ./bindings/python/
          #   with:
          #     name: pypi_files
          #     path: dist
  build-sdist:
    name: build sdist
    needs: [lock_exists]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: PyO3/maturin-action@v1
        with:
          working-directory: ./bindings/python
          command: sdist
          args: --out dist
          rust-toolchain: stable
      - name: Upload wheels
        shell: bash
        run: |
          pip install awscli
          aws s3 sync --exact-timestamps ./bindings/python/dist "s3://tokenizers-releases/python/$DIST_DIR"


  upload_package:
    name: Upload package to PyPi
    runs-on: ubuntu-latest
    needs: [build, build-sdist]

    steps:
      - uses: actions/checkout@v3

      - name: Install Python
        uses: actions/setup-python@v4
        with:
          python-version: "3.12"
          architecture: x64

      - name: Retrieve all wheels
        shell: bash
        run: |
          pip install awscli
          aws s3 sync "s3://tokenizers-releases/python/$DIST_DIR" ./bindings/python/dist

      - name: Upload to PyPi
        working-directory: ./bindings/python
        run: |
          pip install twine
          twine upload dist/* -u __token__ -p "$PYPI_TOKEN"